package com.kmxd.ams.app.archive;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kmxd.ams.app.event.AmsEventPublisher;
import com.kmxd.ams.app.oss.command.CheckTableCmd;
import com.kmxd.ams.client.archive.IArchiveAuthSvc;
import com.kmxd.ams.client.archive.IArchiveFieldSvc;
import com.kmxd.ams.client.archive.IArchiveRuleMainSvc;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.archive.dto.*;
import com.kmxd.ams.client.archive.vo.*;
import com.kmxd.ams.client.event.archive.ArchTypeCountEvent;
import com.kmxd.ams.client.event.catalog.CatalogArchNodeEditEvent;
import com.kmxd.ams.client.event.es.EsCreateIndexEvent;
import com.kmxd.ams.client.jy.IAuthDatabaseSvc;
import com.kmxd.ams.client.jy.IAuthDetailsSvc;
import com.kmxd.ams.client.system.ISysCropSvc;
import com.kmxd.ams.client.system.ISysFondsSvc;
import com.kmxd.ams.client.system.vo.SysCropVO;
import com.kmxd.ams.client.system.vo.SysFondsListVO;
import com.kmxd.ams.core.common.constant.ArchConst;
import com.kmxd.ams.core.common.constant.CacheConst;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.DbTypeEnum;
import com.kmxd.ams.core.common.query.QueryGen;
import com.kmxd.ams.core.config.AmsConfig;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.core.util.SecurityUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveField;
import com.kmxd.ams.infra.archive.entity.ArchiveType;
import com.kmxd.ams.infra.archive.mapper.ArchiveTypeMapper;
import com.kmxd.ams.infra.jy.entity.AuthDatabase;
import com.kmxd.ams.infra.jy.entity.AuthDetails;
import com.kmxd.ams.infra.system.entity.SysCrop;
import com.kmxd.ams.infra.system.mapper.SysFondsMapper;
import com.kmxd.ams.infra.tmpl.dto.ArchTmplBO;
import com.kmxd.ams.infra.tmpl.dto.JsonFieldDto;
import com.kmxd.ams.infra.tmpl.enums.TmplEnum;
import com.kmxd.ams.infra.tmpl.enums.TmplRes;
import com.kmxd.ams.infra.tmpl.util.CreateTableUtils;
import com.kmxd.ams.infra.tmpl.util.ExtFieldUtil;
import com.kmxd.ams.infra.tmpl.util.TmplCommon;
import com.kmxd.ams.infra.tmpl.util.TmplUtils;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 门类|档案库配置主表 服务实现类
 *
 * @author ZuoLG
 * @since 2022-07-15
 */
@Service
@Slf4j
@AllArgsConstructor
@CacheConfig(cacheNames = CacheConst.CACHE_PREFIX_ARCHIVE_TYPE)
public class ArchiveTypeSvcImpl extends ServiceImpl<ArchiveTypeMapper, ArchiveType>
        implements IArchiveTypeSvc {

    private final SysFondsMapper sysFondsMapper;
    private final AmsEventPublisher amsEventPublisher;
    private IArchiveRuleMainSvc archiveRuleMainSvc;
    private IArchiveFieldSvc archiveFieldSvc;
    private ISysFondsSvc sysFondsSvc;
    private CreateTableUtils createTableUtils;
    private JdbcTemplate jdbcTemplate;
    private TmplUtils tmplUtils;
    private TmplCommon tmplCommon;
    private IArchiveAuthSvc archiveAuthSvc;
    private AmsConfig amsConfig;
    private final CheckTableCmd checkTableCmd;

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public Page<ArchiveTypeListVO> selectPage(Page reqPage, ArchiveTypeQueryDTO req) {
        LambdaQueryWrapper<ArchiveType> queryWrapper =
                QueryGen.init(new QueryWrapper<ArchiveType>(), req).lambda();
        queryWrapper.eq(Objects.nonNull(req.getFondsId()), ArchiveType::getFondsId, req.getFondsId());
        queryWrapper.like(StrUtil.isNotBlank(req.getName()), ArchiveType::getName, req.getName());
        Page<ArchiveType> page = this.baseMapper.selectPage(reqPage, queryWrapper);
        Page<ArchiveTypeListVO> voPage = BeanUtil.copyProperties(page, Page.class);
        voPage.setRecords(BeanUtil.copyToList(page.getRecords(), ArchiveTypeListVO.class));
        return voPage;
    }

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public List<ArchiveTypeListVO> selectList(ArchiveTypeQueryDTO req) {

        LambdaQueryWrapper<ArchiveType> queryWrapper =
                QueryGen.init(new QueryWrapper<ArchiveType>(), req).lambda();
        queryWrapper.eq(Objects.nonNull(req.getId()), ArchiveType::getId, req.getId());
        queryWrapper.eq(Objects.nonNull(req.getFondsId()), ArchiveType::getFondsId, req.getFondsId());
        queryWrapper.like(StrUtil.isNotBlank(req.getName()), ArchiveType::getName, req.getName());
        queryWrapper.eq(null != req.getHaveVol(), ArchiveType::getHaveVol, req.getHaveVol());
        queryWrapper.eq(null != req.getHaveBox(), ArchiveType::getHaveBox, req.getHaveBox());
        queryWrapper.eq(
                null != req.getHaveProject(), ArchiveType::getHaveProject, req.getHaveProject());
        queryWrapper.orderByAsc(ArchiveType::getSort);
        List<ArchiveType> list = this.baseMapper.selectList(queryWrapper);
        List<ArchiveTypeListVO> archiveTypeListVOS = BeanUtil.copyToList(list, ArchiveTypeListVO.class);
        //查询所有单位
        ISysCropSvc sysCropSvc = SpringUtil.getBean(ISysCropSvc.class);
        List<SysCrop> sysCrops = sysCropSvc.selectListAll();
        archiveTypeListVOS.forEach(item -> {
            SysCrop sysCrop = sysCrops.stream().filter(x -> ObjectUtil.equal(x.getId(), item.getComId())).findFirst().orElse(null);
            item.setCropInfo(ObjUtil.isEmpty(sysCrop) ? null : BeanUtil.copyProperties(sysCrop, SysCropVO.class));
            item.setLongName(StrUtil.format("[{}]{}", ObjUtil.isEmpty(sysCrop) ? "" : sysCrop.getName(), item.getName()));
        });
        if (BooleanUtil.isTrue(req.getAddAllItem())) {
            ArchiveTypeListVO all = new ArchiveTypeListVO();
            all.setId(null);
            all.setName("全部档案");
            List<ArchiveTypeListVO> allList = Lists.newArrayList();
            allList.add(all);
            allList.addAll(archiveTypeListVOS);
            return allList;
        } else {
            return archiveTypeListVOS;
        }
    }

    @Override
    public List<ArchiveTypeListVO> selectListByAms() {
        List<ArchiveType> list = this.baseMapper.selectListByAms();
        List<ArchiveTypeListVO> voList = BeanUtil.copyToList(list, ArchiveTypeListVO.class);
        //查询所有单位
        ISysCropSvc sysCropSvc = SpringUtil.getBean(ISysCropSvc.class);
        List<SysCrop> sysCrops = sysCropSvc.selectListAll();
        voList.forEach(item -> {
            SysCrop sysCrop = sysCrops.stream().filter(x -> ObjectUtil.equal(x.getId(), item.getComId())).findFirst().orElse(null);
            item.setCropInfo(ObjUtil.isEmpty(sysCrop) ? null : BeanUtil.copyProperties(sysCrop, SysCropVO.class));
            item.setLongName(StrUtil.format("[{}]{}", ObjUtil.isEmpty(sysCrop) ? "" : sysCrop.getName(), item.getName()));
        });

        return voList;
    }

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public List<ArchiveFondsVO> archTypeByCrop(Long roleId) {
        if (ObjectUtil.isEmpty(roleId)) {
            throw BizTipException.instance(ErrorCode.NOT_FOUND, "当前角色ID不能为空！");
        }
        List<SysFondsListVO> fonds = sysFondsSvc.list(SecurityUtil.getCropId());
        // 所有档案档案库
        List<ArchiveType> list = this.list();

        // 查询本单位所有档案库
        List<ArchiveFondsVO> archTypes =
                fonds.stream()
                        .map(
                                item -> {
                                    ArchiveFondsVO archiveFondsVO = new ArchiveFondsVO();
                                    archiveFondsVO.setFondsId(item.getId());
                                    archiveFondsVO.setFondsName(item.getName());
                                    List<String> allIds = Lists.newArrayList();
                                    List<ArchiveTypeListVO> archiveTypeList =
                                            list.stream()
                                                    .filter(archType -> archType.getFondsId().equals(item.getId()))
                                                    .map(
                                                            archiveType -> {
                                                                allIds.add(archiveType.getId().toString());
                                                                return BeanUtil.copyProperties(
                                                                        archiveType, ArchiveTypeListVO.class);
                                                            })
                                                    .collect(Collectors.toList());
                                    // 使用取反的方式，有则不选中
                                    List<String> listFondsArch = Lists.newArrayList();
                                    archiveFondsVO.setArchiveTypeList(archiveTypeList);
                                    archiveFondsVO.setAllArchIds(allIds);
                                    archiveFondsVO.setCheckArchIds(
                                            allIds.stream()
                                                    .filter(checkArch -> !listFondsArch.contains(checkArch))
                                                    .collect(Collectors.toList()));
                                    return archiveFondsVO;
                                })
                        .collect(Collectors.toList());
        return archTypes;
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = {Exception.class, SQLException.class})
    public void add(ArchiveTypeAddDTO req) {
        req.setFondsId(
                ObjectUtil.isNotEmpty(req.getFondsId()) ? req.getFondsId() : SecurityUtil.getFondsId());
        ArchiveType entity = BeanUtil.copyProperties(req, ArchiveType.class);
        entity.setComId(SecurityUtil.getCropId());
        // 1、创建相应的表信息 #表名规则   f{全宗autoIndex}_{第几个档案库}_{类型：doc}
        // 2、创建元数据信息
        // 3、创建档案库
        entity.setId(IdWorker.getId());
        entity.setRpCodeId(ArchConst.GENERAL_KEY);
        entity.setSecretCodeId(ArchConst.GENERAL_KEY);
        // 门类中文名称不能重复
        long countArchName =
                count(
                        Wrappers.<ArchiveType>lambdaQuery()
                                .eq(ArchiveType::getName, req.getName())
                                .eq(ArchiveType::getFondsId, req.getFondsId()));
        if (countArchName > 0) {
            throw BizTipException.instance(
                    ErrorCode.ARCHIVE_DATA_EXIST, StrUtil.format("门类名:[{}]已经存在，请手动处理!", req.getName()));
        }

        String tableSchema;
        if (StrUtil.isBlank(amsConfig.getDbType())
                || StrUtil.equals(DbTypeEnum.MYSQL.getCode(), amsConfig.getDbType())) {
            tableSchema = sysFondsMapper.getDataBaseId();
        } else {
            tableSchema = amsConfig.getDbName();
        }

        tmplUtils
                .getTmpl(req.getManageModel())
                .forEach(
                        tmpl -> {
                            String tableName = getTableName(req.getFondsId(), tmpl.getType());
                            int count = checkTableCmd.getTableCount(tableSchema, tableName);
                            if (count != 0) {
                                throw BizTipException.instance(
                                        ErrorCode.ARCHIVE_DATA_EXIST, StrUtil.format("表:[{}]已经存在，请手动处理!", tableName));
                            }
                            if (BooleanUtil.isTrue(req.getDropTable())) {
                                jdbcTemplate.execute(String.format("DROP TABLE IF EXISTS `%s`; ", tableName));
                            }
                            List<JsonFieldDto> tableField = Lists.newArrayList();
                            // 此处避免copy
                            tableField.addAll(tmpl.getFields());
                            // 添加扩展字段
                            List<JsonFieldDto> extFields = ExtFieldUtil.getExtField(tmpl.getClazz());
                            if (!extFields.isEmpty()) {
                                tableField.addAll(extFields);
                            }
                            List<JsonFieldDto> tableFieldSort =
                                    tableField.stream()
                                            .map(
                                                    item -> {
                                                        item.setDbSort(
                                                                ObjectUtil.isEmpty(item.getDbSort()) ? 200 : item.getDbSort());
                                                        item.setSort(ObjectUtil.isEmpty(item.getSort()) ? 200 : item.getSort());
                                                        return item;
                                                    })
                                            .sorted(Comparator.comparing(JsonFieldDto::getDbSort))
                                            .collect(Collectors.toList());
                            String sql;
                            if (StrUtil.isBlank(amsConfig.getDbType())
                                    || StrUtil.equals(DbTypeEnum.MYSQL.getCode(), amsConfig.getDbType())) {
                                sql = createTableUtils.getTableSql(tableName, req.getName(), tableFieldSort);
                            } else if (StrUtil.equals(DbTypeEnum.PG.getCode(), amsConfig.getDbType())) {
                                sql = createTableUtils.getTableSqlPg(tableName, req.getName(), tableFieldSort);
                            } else if (StrUtil.equals(DbTypeEnum.DM.getCode(), amsConfig.getDbType())) {
                                sql = createTableUtils.getTableSqlDm(tableName, req.getName(), tableFieldSort);
                            } else {
                                throw BizTipException.instance(ErrorCode.VALIDATE_ERROR, "当前数据库类型为适配！");
                            }

                            jdbcTemplate.execute(sql);
                            if (StrUtil.contains(tableName, ArchTmplBO.DOCUMENT)) {
                                entity.setDocTableId(tableName);
                            }
                            if (tmpl.getHaveBox()) {
                                entity.setHaveBox(tmpl.getHaveBox());
                                entity.setBoxTableId(tableName);
                            }
                            if (tmpl.getHaveProject()) {
                                entity.setHaveProject(tmpl.getHaveProject());
                                entity.setProjTableId(tableName);
                            }
                            if (tmpl.getHaveVol()) {
                                entity.setHaveVol(tmpl.getHaveVol());
                                entity.setVolTableId(tableName);
                            }
                            // 创建元数据信息
                            List<ArchiveField> mates = convertFields(tmpl.getFields(), entity.getId(), tableName);
                            if (tmpl.getHaveBox()) {
                                mates.stream()
                                        .forEach(
                                                x -> {
                                                    String docTableId =
                                                            CharSequenceUtil.replace(
                                                                    tableName, ArchTmplBO.BOX, ArchTmplBO.DOCUMENT);
                                                    // 件数 件数=count(唯一ID）
                                                    if ("files_num".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(tableName);
                                                        x.setSummaryField("id");
                                                        x.setSummaryType("count");
                                                    }
                                                    // 总页数=sum(页数）
                                                    if ("page_total".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(docTableId);
                                                        x.setSummaryField("page_num");
                                                        x.setSummaryType("sum");
                                                    }
                                                    // 件号起 件号止=max(件号）
                                                    if ("start_doc_sequence".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(tableName);
                                                        x.setSummaryField("doc_sequence");
                                                        x.setSummaryType("min");
                                                    }
                                                    // 件号止 件号起=max(件号）
                                                    if ("end_doc_sequence".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(tableName);
                                                        x.setSummaryField("doc_sequence");
                                                        x.setSummaryType("max");
                                                    }
                                                });
                            }
                            if (tmpl.getHaveVol()) {
                                mates.stream()
                                        .forEach(
                                                x -> {
                                                    // 卷内文件数=count(唯一ID）
                                                    String docTableId =
                                                            CharSequenceUtil.replace(
                                                                    tableName, ArchTmplBO.VOLUME, ArchTmplBO.DOCUMENT);
                                                    if ("files_num".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(docTableId);
                                                        x.setSummaryField("id");
                                                        x.setSummaryType("count");
                                                    }
                                                    // 总页数=sum(页数）
                                                    if ("page_total".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(docTableId);
                                                        x.setSummaryField("page_num");
                                                        x.setSummaryType("sum");
                                                    }
                                                    // 起始日期=max(日期）
                                                    if ("start_date".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(docTableId);
                                                        x.setSummaryField("doc_date");
                                                        x.setSummaryType("min");
                                                    }
                                                    // 结束日期=min(日期）
                                                    if ("end_date".equals(x.getDbFieldKey())) {
                                                        x.setAttrSummary(true);
                                                        x.setSummaryTableId(docTableId);
                                                        x.setSummaryField("doc_date");
                                                        x.setSummaryType("max");
                                                    }
                                                });
                            }
                            if (tmpl.getHaveProject()) {
                                mates.stream()
                                        .forEach(
                                                x -> {
                                                    // 项目代号不能重复
                                                    if ("proj_code".equals(x.getDbFieldKey())) {
                                                        x.setAttrRepeatWarn(true);
                                                        x.setAttrRepeatWarnArrange(true);
                                                    }
                                                    // 项目状态设置为可编辑,
                                                    if ("status".equals(x.getDbFieldKey())) {
                                                        x.setAttrEdit(true);
                                                    }
                                                });
                            }
                            archiveFieldSvc.saveBatch(mates);
                        });
        entity.setSort((int) (countArchTypeByFondsId(entity.getFondsId())) + 1);
        this.baseMapper.insert(entity);
        // 初始化默认整理规则
        ArchiveRuleMainAddDTO ruleMainAddDTO =
                BeanUtil.copyProperties(entity, ArchiveRuleMainAddDTO.class);
        ruleMainAddDTO.setArchTypeId(entity.getId());
        ruleMainAddDTO.setName(null);
        archiveRuleMainSvc.add(ruleMainAddDTO);
        // 初始化通用权限
        ArchiveAuthAddDTO authDTO =
                tmplCommon.getTempInfo(TmplRes.ARCHIE_COMMON_AUTH.getPath(), ArchiveAuthAddDTO.class);
        authDTO.setArchTypeId(entity.getId());
        archiveAuthSvc.add(authDTO);
        // 添加项目继承关系 项目文件级 所属卷号(vol_arch_code)  继承案卷级 档号(arch_code)
        if (req.getManageModel().equalsIgnoreCase(TmplEnum.project_document.getCode())
                || req.getManageModel().equalsIgnoreCase(TmplEnum.project_volume_document.getCode())) {
            ArchiveFieldQueryDTO queryDTO = new ArchiveFieldQueryDTO();
            queryDTO.setArchTypeId(entity.getId());
            queryDTO.setDbFieldKey(ArchConst.PROJ_CODE);
            List<ArchiveFieldListVO> list = archiveFieldSvc.selectList(queryDTO);
            List<ArchiveField> updateField =
                    list.stream()
                            .filter(item -> !item.getTableId().equalsIgnoreCase(entity.getProjTableId()))
                            .map(
                                    item -> {
                                        ArchiveField field = BeanUtil.copyProperties(item, ArchiveField.class);
                                        field.setAttrExtends(true);
                                        field.setAttrUse(true);
                                        boolean flag =
                                                req.getManageModel()
                                                        .equalsIgnoreCase(TmplEnum.project_volume_document.getCode())
                                                        && field.getTableId().equalsIgnoreCase(entity.getDocTableId());
                                        field.setExtendsTableId(
                                                flag ? entity.getVolTableId() : entity.getProjTableId());
                                        field.setExtendsField(ArchConst.PROJ_CODE);
                                        return field;
                                    })
                            .collect(Collectors.toList());
            archiveFieldSvc.updateBatchById(updateField);
        }
        // 处理案卷文件的继承关系
        if (req.getManageModel().equalsIgnoreCase(TmplEnum.volume_document.getCode())
                || req.getManageModel().equalsIgnoreCase(TmplEnum.project_volume_document.getCode())) {
            ArchiveFieldQueryDTO queryDTO = new ArchiveFieldQueryDTO();
            queryDTO.setArchTypeId(entity.getId());
            queryDTO.setTableId(entity.getDocTableId());
            queryDTO.setDbFieldKey(ArchConst.VOL_ARCH_CODE);
            List<ArchiveFieldListVO> list = archiveFieldSvc.selectList(queryDTO);
            List<ArchiveField> updateField =
                    list.stream()
                            .filter(item -> !item.getTableId().equalsIgnoreCase(entity.getVolTableId()))
                            .map(
                                    item -> {
                                        ArchiveField field = BeanUtil.copyProperties(item, ArchiveField.class);
                                        field.setAttrExtends(true);
                                        field.setAttrUse(true);
                                        field.setExtendsTableId(entity.getVolTableId());
                                        field.setExtendsField(StringUtils.camelToUnderline(ArchConst.ARCH_CODE));
                                        return field;
                                    })
                            .collect(Collectors.toList());
            archiveFieldSvc.updateBatchById(updateField);
        }
        // 分类名称继承设置
        if (req.getManageModel().equalsIgnoreCase(TmplEnum.volume_document.getCode())
                || req.getManageModel().equalsIgnoreCase(TmplEnum.project_volume_document.getCode())) {
            ArchiveFieldQueryDTO queryDTO = new ArchiveFieldQueryDTO();
            queryDTO.setArchTypeId(entity.getId());
            queryDTO.setTableId(entity.getDocTableId());
            queryDTO.setDbFieldKey(ArchConst.CLASSFY_NAME);
            List<ArchiveFieldListVO> list = archiveFieldSvc.selectList(queryDTO);
            List<ArchiveField> updateField =
                    list.stream()
                            .filter(item -> !item.getTableId().equalsIgnoreCase(entity.getVolTableId()))
                            .map(
                                    item -> {
                                        ArchiveField field = BeanUtil.copyProperties(item, ArchiveField.class);
                                        field.setAttrExtends(true);
                                        field.setAttrUse(true);
                                        field.setExtendsTableId(entity.getVolTableId());
                                        field.setExtendsField(StringUtils.camelToUnderline(ArchConst.CLASSFY_NAME));
                                        return field;
                                    })
                            .collect(Collectors.toList());
            archiveFieldSvc.updateBatchById(updateField);
        }

        archiveFieldSvc.clearAllCache();
        amsEventPublisher.publishEvent(new ArchTypeCountEvent());
        // 门类创建,删除存在的index,重新创建
        amsEventPublisher.publishEvent(new EsCreateIndexEvent(entity.getId().toString(), true));
    }

    /**
     * 数据字段转换
     *
     * @param list
     * @return
     */
    private List<ArchiveField> convertFields(
            List<JsonFieldDto> list, long archTypeId, String tableName) {
        List<ArchiveField> mates =
                list.stream()
                        .map(
                                item -> {
                                    ArchiveField field = new ArchiveField();
                                    BeanUtil.copyProperties(item, field);
                                    field.setArchTypeId(archTypeId);
                                    field.setTableId(tableName);
                                    field.setDbFieldKey(item.getCode());
                                    field.setDbFieldName(item.getName());
                                    field.setDbType(item.getType());
                                    field.setDbLength(item.getLength());
                                    field.setDbIsNull(Boolean.TRUE);
                                    field.setXmlAlias(item.getName());
                                    field.setXmlExport(Boolean.TRUE);
                                    field.setAttrSystem(item.getSystemtField());
                                    field.setDbDefault(item.getDefaultvalue());
                                    field.setDictShow(ObjectUtil.isNotEmpty(item.getCode()) ? "label" : "");
                                    field.setDictStorage(
                                            ObjectUtil.isEmpty(item.getDictStorage()) ? "label" : item.getDictStorage());
                                    field.setAliasEn(item.getCode());
                                    // 设置汇总字段
                                    return field;
                                })
                        .collect(Collectors.toList());
        return mates;
    }

    /**
     * 获取档案库数量
     *
     * @param fondsId
     * @return
     */
    @Override
    public long countArchTypeByFondsId(long fondsId) {
        return this.baseMapper.countArchTypeByFonds(fondsId);
    }

    @Override
    public String getTableName(long fondsId, String model) {
        int autoIndex = sysFondsSvc.getById(fondsId).getAutoIndex();
        long num = countArchTypeByFondsId(fondsId);
        // f{全宗autoIndex}_{第几个档案库}_{类型：doc}
        return StrUtil.format("f{}_{}_{}", autoIndex, num + 1, model);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(ArchiveTypeEditDTO req) {
        ArchiveType entity = BeanUtil.copyProperties(req, ArchiveType.class);
        this.baseMapper.updateById(entity);
        amsEventPublisher.publishEvent(new CatalogArchNodeEditEvent(entity.getId()));
    }

    @CacheEvict(allEntries = true)
    @Override
    public void openArchiveType(ArchiveTypeOpenDTO req) {
        if (ObjectUtil.isEmpty(req.getArchTypeIds()) || req.getArchTypeIds().isEmpty()) {
            throw BizTipException.instance(ErrorCode.ARCHIVE_DATA_INVALIDED, "请设置需要修改的门类！");
        }
        List<ArchiveTypeListVO> amsList = this.selectListByAms();
        List<ArchiveType> saveList =
                amsList.stream()
                        .filter(x -> req.getArchTypeIds().contains(x.getId()))
                        .map(
                                item -> {
                                    return BeanUtil.copyProperties(item, ArchiveType.class);
                                })
                        .collect(Collectors.toList());

    List<Long> saveIds = saveList.stream().map(ArchiveType::getId).collect(Collectors.toList());

    // 获取数据库中已有的档案库
    List<ArchiveType> listDb = this.baseMapper.selectList(Wrappers.lambdaQuery());
    // 找出删除的数据
    String deleteIds =
        listDb.stream()
            .filter(x -> !saveIds.contains(x.getId()))
            .map(item -> String.valueOf(item.getId()))
            .collect(Collectors.joining(","));
    if (ObjUtil.isNotEmpty(deleteIds)) {
      remove(deleteIds);
    }
    this.saveOrUpdateBatch(saveList);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String ids) {
        Set<Long> idList = IdUtil.split(ids);
        this.baseMapper.deleteBatchIds(idList);
        IAuthDatabaseSvc authDatabaseSvc = SpringUtil.getBean(IAuthDatabaseSvc.class);
        //删除用户授权部分
        LambdaQueryWrapper<AuthDatabase> deleteWrapper = Wrappers.lambdaQuery();
        deleteWrapper.in(AuthDatabase::getArchivesId, idList);
        authDatabaseSvc.remove(deleteWrapper);

        IAuthDetailsSvc authDetailsSvc = SpringUtil.getBean(IAuthDetailsSvc.class);
        // 删除不是此门类的个人数据
        if (!idList.isEmpty()) {
          LambdaQueryWrapper<AuthDetails> deleteArchWrapper = Wrappers.lambdaQuery();
          deleteArchWrapper.notIn(AuthDetails::getArchivesId, idList);
          authDetailsSvc.getBaseMapper().delete(deleteArchWrapper);
        }
    }

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public ArchiveTypeVO view(Long id) {
        ArchiveType entity = this.baseMapper.selectById(id);
        return BeanUtil.copyProperties(entity, ArchiveTypeVO.class);
    }

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public FondsOrArchiveTypeVO getFondsOrArchiveTypeByCrop() {
        FondsOrArchiveTypeVO archiveTypeVO = new FondsOrArchiveTypeVO();
        LambdaQueryWrapper<ArchiveType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.orderByAsc(ArchiveType::getSort);
        queryWrapper.eq(ArchiveType::getComId, SecurityUtil.getCropId());
        List<ArchiveType> list = this.baseMapper.selectList(queryWrapper);
        archiveTypeVO.setFondsList(sysFondsSvc.list(SecurityUtil.getCropId()));
        archiveTypeVO.setArchiveTypeList(list);
        return archiveTypeVO;
    }

    @CacheEvict(allEntries = true)
    @Override
    public void clearAllCache() {
        log.info("清除系统缓存");
    }
}
